package com.sinaapp.gavinzhang.GSpider.process;

import com.sinaapp.gavinzhang.GSpider.config.Constants;

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.zip.GZIPInputStream;

/**
 * @author gavin
 * @version 1.0
 * @date 2015/9/10
 * @description 获取网址，不使用Jsoup的连接
 */
public class HttpProcessor {
    //构造函数可接入
    private int timeout;
    private String method;
    private String url;

    //非构造函数接入
    private HashMap<String,String> headers;
    private String charset;
    private String cookie;

    public HttpProcessor(String url) {
        this(url,10000, Constants.GET);
    }

    public HttpProcessor(String url,int timeout)
    {
        this(url,timeout,Constants.GET);
    }

    public HttpProcessor(String url,int timeout, String method) {
        this.url = url;
        this.timeout = timeout;
        this.method = method;
        headers = new HashMap<>();
        //setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");

    }

    public static String getCharSet(String contentType) {
        if (contentType == null) {
            return Constants.UTF8;
        }
        if (contentType.contains(Constants.UTF8)) {
            return Constants.UTF8;
        }
        if (contentType.contains(Constants.GBK)) {
            return Constants.GBK;
        }
        if (contentType.contains(Constants.GB2312)) {
            return Constants.GB2312;
        }
        if (contentType.contains(Constants.GB18030)) {
            return Constants.GB18030;
        }
        return Constants.UTF8;
    }

    public static String getCookie(HttpURLConnection httpURLConnection) {
        return httpURLConnection.getHeaderField("Set-Cookie")==null?"":httpURLConnection.getHeaderField("Set-Cookie");
    }

    public HttpProcessor setHeader(HashMap<String,String> headers) {
        this.headers.putAll(headers);
        return this;
    }

    public HttpProcessor setHeader(String key,String value) {
        headers.put(key, value);
        return this;
    }

    public int getStatus() {
        try {
            return checkStatus();
        } catch (IOException e) {
            return 800;
        }
    }

    private int checkStatus() throws IOException {
        HttpURLConnection httpURLConnection = (HttpURLConnection) new URL(url).openConnection();

        //设置超时等信息
        httpURLConnection.setConnectTimeout(timeout);
        httpURLConnection.setRequestMethod(method);
        //传输header信息
        if (headers.size() != 0) {
            Set<Map.Entry<String,String>> entrys = headers.entrySet();
            for (Map.Entry<String,String> entry : entrys) {
                if (entry.getKey() != null)
                    httpURLConnection.setRequestProperty(entry.getKey(),entry.getValue());
            }
        }
        int status = httpURLConnection.getResponseCode();
        httpURLConnection.disconnect();
        return status;
    }

    /**
     * @throws IOException
     * @exception IOException url error or method not support or connect error
     * */
    public String getContent() throws IOException {
        HttpURLConnection httpURLConnection = (HttpURLConnection) new URL(url).openConnection();

        //设置超时等信息
        httpURLConnection.setConnectTimeout(timeout);
        httpURLConnection.setRequestMethod(method);
        //传输header信息
        if (headers.size() != 0) {
            Set<Map.Entry<String,String>> entrys = headers.entrySet();
            for (Map.Entry<String,String> entry : entrys) {
                if (entry.getKey() != null)
                    httpURLConnection.setRequestProperty(entry.getKey(),entry.getValue());
            }
        }

        charset = getCharSet(httpURLConnection.getContentType());
        cookie = getCookie(httpURLConnection);
        return  getContent(httpURLConnection);
    }

    private String getContent(HttpURLConnection httpURLConnection) throws IOException {
        InputStream inputStream = new BufferedInputStream(httpURLConnection.getInputStream());
        String encoding = httpURLConnection.getHeaderField("Content-Encoding");
        if (encoding!=null && encoding.equals("gzip")) {
            //支持gzip压缩
            inputStream = new GZIPInputStream(inputStream);
        }
        /**来源自bytearraybuffer*/

        int count = 0;
        byte[] buf = new byte[1024];
        while(true) {
            int cap = buf.length - count;
            int sz = inputStream.read(buf, count, cap);
            if(sz < 0) {
                break;
            }
            count += sz;
            if(cap == sz) {
                int newcount = buf.length*2;
                if(newcount > buf.length) {
                    byte[] newbuf = new byte[Math.max(buf.length << 1, newcount)];
                    System.arraycopy(buf, 0, newbuf, 0, count);
                    buf = newbuf;
                }
            }
        }
        inputStream.close();

        return new String(buf,0,count,charset);
    }

    public static void main(String[] args)
    {
        HttpProcessor httpProcessor = new HttpProcessor("http://www.zhihu.com");


        httpProcessor.setHeader("Cookie", "_za=72d21033-749c-4b9c-993a-3427d3a37a4a; _ga=GA1.2.361559073.1432648245; z_c0=\"QUFEQU5ZVWJBQUFYQUFBQVlRSlZUWkhiXzFXRG9aR0NNcHlMSERqRXdLVE9MVmZYdVlzMVV3PT0=|1440239249|f2f882f013172cfebf7747aff898b46f0b58c7bc\"; _xsrf=da715a977479e1e9a05109beeb41c4e5; q_c1=f5a918326c184f02a1c45c7ef6cc8803|1441859927000|1432648249000; __utmt=1; __utma=51854390.361559073.1432648245.1441791168.1441859929.61; __utmb=51854390.7.9.1441860155555; __utmc=51854390; __utmz=51854390.1441530611.48.11.utmcsr=zhihu.com|utmccn=(referral)|utmcmd=referral|utmcct=/search; __utmv=51854390.100-1|2=registration_date=20130522=1^3=entry_date=20130522=1");
        try {
            System.out.println(httpProcessor.getContent());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String getCookie() {
        return cookie;
    }
}
